import java.util.HashMap;


public class RobotFactory {
	
	private HashMap<String,RobotFac> robotFactMap;
	private HashMap<String,RobotFac_withAdd> specialRobotFactMap;
	
	//create hash map of robot factories - keys are their names
	public RobotFactory(){
	   robotFactMap = new HashMap<String,RobotFac> ();
	   robotFactMap.put("RV1", new RV1Fac());
	   robotFactMap.put("RV2", new RV2Fac());
	   robotFactMap.put("Aibo", new AiboFac());
	   
	   specialRobotFactMap = new HashMap<String, RobotFac_withAdd>(); 
	   specialRobotFactMap.put("smartKit", new SmartRobotFac());
	   specialRobotFactMap.put("arm", new WithArmFac());
	   specialRobotFactMap.put("all", new WithAllRobotFac());
	}
	
	//check if robot type exists
	public boolean exists(String type){return robotFactMap.containsKey(type);}
	
	//check if addition exist
	public boolean addExists(String add){return specialRobotFactMap.containsKey(add);}
	
	//create basic robot according to name
	public Robot createRobot(String type, String name, Position p){
	   return (robotFactMap.get(type)).create(name,	p);
	}
	//create robot with addition according to name
	public Robot createRobotWithAdd(String type, String inner_type, String name, Position p)
	{
		return (specialRobotFactMap.get(type)).create(name, inner_type, p);
	}
	
	/***_________________________________________________________________***/
	//interface and implemented classes of basic robots
	private interface RobotFac{
		 public Robot create(String name, Position p);
	}
	
	private class RV1Fac implements RobotFac{
		 public Robot create(String name, Position p){ return new RV1(name, p);}
	}
	
	private class RV2Fac implements RobotFac{
		 public Robot create(String name, Position p){ return new RV2(name, p);}
	}
	
	private class AiboFac implements RobotFac{
		 public Robot create(String name, Position p){ return new Aibo(name, p);}
	}
	
	/***________________________________________________________________***/
	//interface and implemented classes for robots with additions
	private interface RobotFac_withAdd{
		 public Robot create(String name, String inner_type, Position p);
	}
	
	private class WithArmFac implements RobotFac_withAdd{
		 public Robot create(String name,String inner_type, Position p){
			 System.out.format("new Robot with arm of %s at %s named %s\n",
					 					inner_type, p.toString(),name);
			 
			 return new ArmAddition(robotFactMap.get(inner_type).create(name,p));
		}
	}
	
	private class SmartRobotFac implements RobotFac_withAdd{
		 public Robot create(String name,String inner_type, Position p){
			 System.out.format("new Smart Robot of %s at %s named %s\n", 
					 inner_type, p.toString(),name);
			 return new SmartRobot(robotFactMap.get(inner_type).create(name,p));
		}
	}
	
	private class WithAllRobotFac implements RobotFac_withAdd{
		 public Robot create(String name,String inner_type, Position p){
			 System.out.format("new Robot with arm of Smart Robot of %s at %s named %s\n",
						inner_type, p.toString(), name);
			 SmartRobot sr = new SmartRobot(robotFactMap.get(inner_type).create(name,p));
			 return new ArmAddition(sr);}
	}
	 
}




